//////////////////////////////////////////////////////////////////////////

#ifndef _FIELD_H_
#define _FIELD_H_


#ifndef _LAYER_H_
#include "layer.h"
#endif

#ifndef _SERVERSTATE_H_
#include "serverstate.h"
#endif

#ifndef _MUTEX_H_
#include "mutex.h"
#endif

#ifndef _CLIENTBATTLEFIELD_H_
#include "clientbattlefield.h"
#endif

#include <queue>

struct SDL_Surface;
class GUI_ImageSurface;
class ServerStatePacket;
struct Mix_Chunk;

class GUI_Field : public GUI_Layer
{
//////////////////////////////////////////////////////////////////////////

public:

//////////////////////////////////////////////////////////////////////////

    GUI_Field();
    virtual ~GUI_Field();

    virtual bool Render(SDL_Surface *_mainSurface, bool _repaint); //??
    virtual void Resize(); //??
        
    /** Key change handler */
//    virtual int OnKeyChanged(Input* _input); //??

    /** Mouse position change handler */
//    virtual int OnMousePositionChanged(Input* _input); //??
    void DrawBackground(const Points& _points);
    /** Add data to render queue */
    void AddStateToRenderQueue( const ServerStatePacket& _packet );

    void SetID( int _ID );   

//////////////////////////////////////////////////////////////////////////

private:

//////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////


    /** Every time we perform a render, we have to draw server state on the screen.
    Server packets with that state come to client ~30 times per second.
    Rendering could be much faster, for example 100 times per second.
    Thats why we need to integrate between those 30 states to get 100 states.
    We always integrate between 2 states to get one INTERMEDIATE state. */


    /** First state being integrated */
    ServerState m_FirstState;


    /** Second state being integrated */
    ServerState m_SecondState;


    /** Integration coefficient, telling where exactly 
    we are between first and second ServerState.
    If it is 0 - we are exactly at first state,
    if it is 1 - we are exactly at first second state,
    if it is 0.5 - we are exactly between first and second state */
    double m_FirstToSecondCoeff;

    /** Fetches first and second states and saves a coefficient.
    Returns true if fetching have been done successfully
    and render should be performed. */
    bool FetchTwoStatesAndCoeff();


    /** Render battlefield */
    void RenderBattlefield(SDL_Surface *_mainSurface);


////////////////////////////////////////////////////////////////////////////////

    /** [Utility type]: Battlefield state and time of its creation */
    typedef std::pair<size_t, ServerState> RenderState;


    /** [Utility type]: Queue of render states */
    class RenderQueue : public std::deque<RenderState>, public Mutex {};

    void RedrawBackground();

//    Mix_Chunk *m_ShootSound;
    SDL_Surface *m_BackSurface;
    Points m_Points;

    /** Render queue */
    RenderQueue m_RenderQueue;

    /** Client battlefield */
    ClientBattlefield m_Battlefield;

    GUI_ImageSurface *m_Background;
    GUI_ImageSurface *m_Players[6]; //Currently 6 player models. Need refactoring here.
    GUI_ImageSurface *m_Highlight;
    GUI_ImageSurface *m_HUDBack;
    GUI_ImageSurface *m_Bullet;
    GUI_ImageSurface *m_Wall;
    GUI_ImageSurface *m_Heart;

    int m_ID;
//////////////////////////////////////////////////////////////////////////
};


//////////////////////////////////////////////////////////////////////////

#endif

//////////////////////////////////////////////////////////////////////////
